package com.seafwg.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.seafwg.domain.User;
import com.seafwg.domain.UserDemo;
import com.seafwg.domain.VO.UserVo;
import com.seafwg.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @Author seafwg
 * @Date 2022/2/17 9:41 上午
 * @Version 1.0
 * @description xxx
 */
@CrossOrigin
@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    //页面跳转：1.直接返回字符串。2.返回ModelAndView
    @RequestMapping("/save")
    public String save() {
        userService.save();
        System.out.println("UserController exe...");
        return "demo";
    }

    //页面跳转：返回ModelAndView
    // 1.直接返回ModelAndView
    @RequestMapping("/save1")
    public ModelAndView save1() {
        ModelAndView modelAndView = new ModelAndView();
        //设置viewName的值，值为跳转的路径
        modelAndView.addObject("username", "seafwg");
        //"forward:/demo" || "redirect:/demo" 转发和重定向
        modelAndView.setViewName("demo");
        return modelAndView;
    }

    //页面跳转：向request域中存储数据
    @RequestMapping("/save2")
    public String save2(HttpServletRequest request) {
        request.setAttribute("username", "seafwg");
        return "demo";
    }

    //几种常见模式:
    // 1.创建ModelAndView,以参数的形式传递，由框架创建
    @RequestMapping("/save3")
    public ModelAndView save3(ModelAndView modelAndView) {
        modelAndView.setViewName("demo");
        modelAndView.addObject("username", "seafwg");
        return modelAndView;
    }

    // 2.返回形式以字符串的形式返回页面跳转，数据由Model添加
    @RequestMapping("/save4")
    public String save4(Model model) {
        model.addAttribute("username", "seafwg");
        return "demo";
    }

    //============================== 数据返回 ================================//
    // springMvc数据响应 -- 添加响应注解@Response

    // 1.返回字符串：
    // @ResponseBody
    @RequestMapping("/res")
    public String res() {
        return "hello SpringMVC res...";
    }

    // 通过response返回字符串数据
    @RequestMapping("/res1")
    public void res1(HttpServletResponse response) throws IOException {
        response.getWriter().print("hello springMVC res1...");
    }

    // 使用Jackson对字符串进行转换
    @RequestMapping("/res2")
    public String res2() throws JsonProcessingException {
        User user = new User();
        user.setUsername("seafwg");
        user.setAge(23);

        // 生成ObjectMapper实例，利用实例的writeValueAsString(user)方法转换成json格式的字符串
        ObjectMapper objectMapper = new ObjectMapper();
        String valueAsString = objectMapper.writeValueAsString(user);

        return valueAsString;
    }

    // 使用配置的jackson对对象进行转换
    @RequestMapping("/res3")
    public User res3(User user) {
        user.setUsername("seafwg123");
        user.setAge(22);
        return user;
    }

    //============================== 接收数据 =================================//
    // 1.接收普通数据：基本数据类型-字符串
    @RequestMapping("/req")
    public void request(String name, int age) {
        System.out.println(name);
        System.out.println(age);
    }

    // 2.接收pojo类型参数-Controller中的业务方法的POJO参数的属性名与请求参数的name一致，参数值会自动映射匹配
    @RequestMapping("/req1")
    public User request1(User user) {
        System.out.println(user);
        return user;
    }

    // 3.接收数组类型
    @RequestMapping("/req2")
    public void request2(String attrs) {
        System.out.println(Arrays.asList(attrs));
    }

    // 4.接收集合类型参数
    @RequestMapping("/req3")
    public UserVo request3(UserVo userVo) {
        System.out.println(userVo);
        return userVo;
    }

    // @RequestBody注解接收
    @RequestMapping(value="/req4")
    public void request4(@RequestBody List<User> userList) {
        System.out.println(userList);
    }

    @RequestMapping("/req5")
    public void request5(@RequestParam(value = "name", required = false, defaultValue = "seafwg") String name) {
        System.out.println(name);
    }

    //================================ RESTful =================================//
    // 地址末尾{variable}，后端和前端注意请求类型，方法的参数中使用@PathVariable注解进行获取参数
    @RequestMapping(value = "/restful/{id}", method = RequestMethod.GET)
    public void restful(@PathVariable(name = "id") Integer id) {
        System.out.println(id);
    }

    // test vue3 前端useRequestApi...
    @RequestMapping("/info")
    public List<UserDemo> result() {
        System.out.println("123");
        List<UserDemo> userDemoList = new ArrayList<>();
        UserDemo userDemo = new UserDemo();
        userDemo.setId(123);
        userDemo.setName("seafwg");
        userDemo.setWork("developer");

        userDemoList.add(userDemo);
        System.out.println(userDemoList);

        return userDemoList;
    }

    // 数据转换测试接口 - 通过配置converter修改时间格式
    @RequestMapping("/date")
    public void toDate(Date date) {
        System.out.println(date);
    }

    // 获取servlet相关信息
    @RequestMapping("/servlet")
    public void toServlet(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
        System.out.println(request);
        System.out.println(response);
        System.out.println(session);
    }

    // 获取请求头信息
    // @RequestHeader: 获取请求头的注解
    // @CookieValue: 获取Cookie的注解
    @RequestMapping("/header")
    public void toHeader(@RequestHeader(value = "User-Agent", required = false) String header, @CookieValue(value = "JSESSIONID", required = false) String jsessionid) {
        System.out.println(header);
        System.out.println("====================");
        System.out.println(jsessionid);
    }

    // 但文件文件上传：
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public void uploadFile(String name, MultipartFile file) {
        System.out.println(name);
        System.out.println("=====================");
        System.out.println(file.getOriginalFilename());
    }

    // 多文件上传 接收一个MultipartFile[]数组
    @RequestMapping(value = "/uploads", method = RequestMethod.POST)
    public void uploadFiles(MultipartFile[] files) {
        for (MultipartFile multipartFile : files) {
            System.out.println(multipartFile.getOriginalFilename());
        }
    }
}
